#include "sysdialog.h"

#include<unistd.h>
#include<string.h>
#include<stdio.h>
#include<fcntl.h>
#include<termios.h> 
#include <QDebug>
#include <wiringPi.h>

#define COM0        "/dev/ttyAMA0"
#define MAX_DAY 6
#define DEV_F_DHT   "/dev/dht11"

//pi3
unsigned int GPIO = 4;//模块GPIO脚
//#define DPRINTK(x...) printf(x);
#define DPRINTK(x...)

#define ARM

SysDialog::SysDialog( QWidget *parent)
    : QDialog( parent)
{

    this->setMinimumSize(800,480);
    this->setMaximumSize(800,480);
    this->setWindowFlags(Qt::FramelessWindowHint);//去掉标题栏 
    this->setWindowIcon(QPixmap( ":/images/3.png") );
    this->setWindowTitle(tr("Air监控系统"));
    label_pic_bg = new QLabel(this);
    label_pic_bg->setGeometry(QRect(0, 0, 800, 480));
    label_pic_bg->setPixmap(QPixmap(":/images/air_bg1.jpg"));
    label_pic_bg->setScaledContents(true);


    //初始化今日天气界面
    showToday = new ShowToday(this);
   // showToday->hide();

    //初始化一周天气界面,postion value
    int x = 195;
    for(int i=0;i<MAX_DAY;i++){
        showWeek[i] = new DayData(this);
        showWeek[i]->setVal(x,60,QString::number(i));
        showWeek[i]->hide();
        x += 90;
    }

    //初始化空气质量界面

    showAqi = new ShowAqi(this);
    showAqi->hide();


    //初始化设置界面
    sysSet = new SysSet(this);
    sysSet->hide();
    connect(sysSet,SIGNAL(hourChange(int)),this,SLOT(setHour(int)) );

//    QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间

    //显示时间
    sysTime = new ShowLabel(this);
    sysTime->addFontSize(6);
    sysTime->setGeometry(80,8,80,50);
//    sysTime->setText(time.toString("hh:mm"));
    flag_time=0;

    //显示按钮
    today = new Button(this);
    today->setButtonPicture(QPixmap( ":/images/air_button1.png"));
    today->setPressPicture(QPixmap( ":/images/air_button11.png"));
    today->setReleasePicture(QPixmap( ":/images/air_button1.png"));
    today->setEnterPicture(QPixmap( ":/images/air_button11.png"));
    today->setReleasePicture(QPixmap( ":/images/air_button1.png"));
    today->set_X_Y_width_height(10,120,130,50);
    connect(today,SIGNAL(clicked()),this,SLOT(goShowToday()) );

    week = new Button(this);
    week->setButtonPicture(QPixmap( ":/images/air_button2.png"));
    week->setPressPicture(QPixmap( ":/images/air_button21.png"));
    week->setReleasePicture(QPixmap( ":/images/air_button2.png"));
    week->setEnterPicture(QPixmap( ":/images/air_button21.png"));
    week->setReleasePicture(QPixmap( ":/images/air_button2.png"));
    week->set_X_Y_width_height(10,190,130,50);
    connect(week,SIGNAL(clicked()),this,SLOT(goShowWeek()) );

    aqi = new Button(this);
    aqi->setButtonPicture(QPixmap( ":/images/air_button4.png"));
    aqi->setPressPicture(QPixmap( ":/images/air_button41.png"));
    aqi->setReleasePicture(QPixmap( ":/images/air_button4.png"));
    aqi->setEnterPicture(QPixmap( ":/images/air_button41.png"));
    aqi->setReleasePicture(QPixmap( ":/images/air_button4.png"));
    aqi->set_X_Y_width_height(10,260,130,50);
    connect(aqi,SIGNAL(clicked()),this,SLOT(goShowAqi()) );


    systemSet = new Button(this);
    systemSet->setButtonPicture(QPixmap( ":/images/air_button3.png"));
    systemSet->setPressPicture(QPixmap( ":/images/air_button31.png"));
    systemSet->setReleasePicture(QPixmap( ":/images/air_button3.png"));
    systemSet->setEnterPicture(QPixmap( ":/images/air_button31.png"));
    systemSet->setReleasePicture(QPixmap( ":/images/air_button3.png"));
    systemSet->set_X_Y_width_height(10,330,130,50);
    connect(systemSet,SIGNAL(clicked()),this,SLOT(goSet()) );



    myProcess = new QProcess(parent);

    //get day_date from python file,update show
    this->get_day_value();
    showToday->updateVal(dayArr);

    this->get_week_value();
    for(int i=0;i<MAX_DAY;i++){
        showWeek[i]->updateVal(weekArr[i]);
    }

    aqiArr[0] = dayArr[13];//pm2.5
    aqiArr[1] = dayArr[12];//pm10
    aqiArr[2] = dayArr[15];//aqi
    aqiArr[3] = aqiArr[0];//pm2.5 local
    aqiArr[4] = dayArr[0];


    showAqi->updateVal(aqiArr);

    QFile f("/home/pi/timer_file");
    if(!f.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Open failed." << endl;
        hourNum = 6;

    }else{
        QTextStream fStream(&f);
        QString readBuf =  fStream.readLine();
        hourNum = readBuf.toInt();
        f.close();
    }
    QString HourN = QString::number(hourNum);
    sysSet->setSysInit(dayArr[0],HourN);

    temp_timer = 0;
    net_timer = 0;
#ifdef ARM
    DevInit();
#endif
    //计时器对象，500ms钟发送一个timeout()信号，调用showState()函数
    QTimer *timer = new QTimer(this);
    timer->start(1000);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateSYS()));

}





void SysDialog::goShowToday()
{
    if( !(showWeek[0]->isHidden()) ){
        for(int i=0;i<MAX_DAY;i++)
            showWeek[i]->hide();
    }

    if( !(showAqi->isHidden()) )
       showAqi->hide();

    if( !(sysSet->isHidden()) )
       sysSet->hide();

    if( showToday->isHidden())
        showToday->show();
}


void SysDialog::goShowWeek()
{


    if( !(showToday->isHidden()) )
        showToday->hide();


    if( (showWeek[0]->isHidden()) ){
        for(int i=0;i<MAX_DAY;i++)
            showWeek[i]->show();
    }

    if(!showAqi->isHidden())
        showAqi->hide();


    if( !(sysSet->isHidden()) )
       sysSet->hide();

}

void SysDialog::goShowAqi()
{
    if( !(showToday->isHidden()) )
        showToday->hide();


    if( !(showWeek[0]->isHidden()) ){
        for(int i=0;i<MAX_DAY;i++)
            showWeek[i]->hide();
    }

    if( !(sysSet->isHidden()) )
       sysSet->hide();

    if(showAqi->isHidden())
        showAqi->show();


}


void SysDialog::goSet()
{
    if( !(showToday->isHidden()) )
        showToday->hide();


    if( !(showWeek[0]->isHidden()) ){
        for(int i=0;i<MAX_DAY;i++)
            showWeek[i]->hide();
    }


    if(!showAqi->isHidden())
        showAqi->hide();

    if(sysSet->isHidden())
        sysSet->show();


    sysSet->setSysInit(dayArr[0],QString::number(hourNum));

}


int SysDialog::read_dht(unsigned char* U8_data)
{
        int l_flag=0,h_flag=0,flag=0;
        int i=0,j=0;
        int bit_flag[40];
        unsigned tmp;
        unsigned char  U8comdata,U8temp[40];

        DPRINTK("DHT11 init...");
        //GPIO设置为输出
        pinMode(GPIO, OUTPUT);//设置输出
        //输出0
        digitalWrite(GPIO, LOW);  //输出低电平
        //延时19ms
        //usleep(18*1000);
        delay(18);
        //输出1
        digitalWrite(GPIO, HIGH);  //输出高电平
        //延时30us
        //usleep(20);
        delayMicroseconds(35);
        //设置为输入
        pinMode(GPIO,INPUT);//设置输入
        //读GPIO
        tmp = digitalRead(GPIO) ;
//      DPRINTK("gpio=%d\n",tmp);
        if(!tmp)
        {
                while(!(digitalRead(GPIO)) ){
                        if((l_flag++)>85) break;
                        delayMicroseconds(1);
                }//从机80us低电平

                while(digitalRead(GPIO)){
                        if((h_flag++)>85) break;
                        delayMicroseconds(1);
                }//从机80us高电平
                //read 40bit data
                for(i=0;i<40;i++){
                        flag = 0;
                        while(!(digitalRead(GPIO)) ){
                                if((flag++)>70) break;
                                delayMicroseconds(1);
                        }//从机50us低电平
                        flag =0;
                        while(digitalRead(GPIO) ){
                                if((flag++)>90) break;
                                delayMicroseconds(1);
                        }//从机高电平//高电平大于70us为"1",否则26-28us为"0"

                        if(flag>30){
                                U8temp[i]=1;
                        }else{
                                U8temp[i]=0;
                        }
                        bit_flag[i]=flag;
                }
                for(i=0;i<40;i++){
                        U8comdata<<=1;
                        U8comdata|=U8temp[i];
                        if((i+1)%8 == 0){
                                U8_data[j]=U8comdata;
                                j++;
                        }
//                      DPRINTK("[%d]flag=%d,val=%d--",i,bit_flag[i],U8temp[i]);
                }
                DPRINTK("L 80us flag=%d\n",l_flag);
                DPRINTK("H 80us flag=%d \n",h_flag);
        }else{DPRINTK("L err..\n");}
        return 0;
}






int SysDialog::get_dht_data(void)
{
        char crr;
        int s;
        unsigned char data[5];

        bzero(data,5);
        read_dht(data);
        crr = 0;

        for(s=0;s<4;s++){
//                printf("data[%d]=%x\n",s,data[s]);
                crr+=data[s];
        }
//        printf("data[4]=%x,crr=%x\n",data[4],crr);

        if(crr==data[4]){
                humi = data[0];
                temp = data[2];
//                printf("\n+---RH=%d %%,T=%d oC.\n",humi,temp);
        }else{
                printf("crr err %X\n",crr);
                return -1;
        }
        return 0;
}




int SysDialog::DevInit(void){
    fd_pm25 = ::open(COM0,O_RDONLY);
    if(fd_pm25 < 0){
            info = "Can't Open COM!";
            info += COM0;
            return -1;
    }
    init_com(fd_pm25);

    info = "PM2.5 modules init OK.";
//    linePM25->setText(info);

    //dht11 init
    if(wiringPiSetup()==-1){
                printf("pi setup err...\n");
                return -1;
    }

    return 0;
}



void SysDialog::init_com(int fd)
{
	struct termios newtio;
	struct termios oldtio;
	bzero(&newtio,sizeof(struct termios));	

	tcgetattr(fd,&oldtio);
	newtio.c_cflag |= CLOCAL | CREAD;
	cfsetispeed(&newtio,B2400);
	cfsetospeed(&newtio,B2400);
	printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag &= ~CSIZE;
	printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag |= CS8;
	printf("c_cflag=%x\n",newtio.c_cflag);
	newtio.c_cflag &= ~PARENB;
	newtio.c_iflag &= ~INPCK;
	newtio.c_cflag &= ~CSTOPB;
	newtio.c_cc[VTIME] = 0;
	newtio.c_cc[VMIN] = 0;
	//设置原始模式
	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ 
	newtio.c_oflag &= ~OPOST; /*Output*/
	//设置终端模式
	//newtio.c_lflag |= (ICANON | ECHO | ECHOE | ISIG); /*Input*/ 
	//newtio.c_oflag |= OPOST; /*Output*/
	tcflush(fd,TCIOFLUSH);
	tcsetattr(fd,TCSANOW,&newtio);
}


int SysDialog::da_pro(char* da_buf)
{
	
	unsigned char crr;
	double vout;
	int ud,i;

	if(da_buf==NULL)
		return -1;
	for(i=0;i<10;i++){
        if(da_buf[i] == 0xAA)
			break;
	}

    if(da_buf[i+0] != 0xAA || da_buf[i+6] != 0xFF)
		return -1;
	
	crr = da_buf[i+1] + da_buf[i+2] + da_buf[i+3] + da_buf[i+4];

	if(da_buf[i+5] != crr)
		return -1;

	vout = (da_buf[i+1]*256+da_buf[i+2])/1024.0*8.0;
	ud = 800 * vout;
	return ud;
}





//鄂州$2017-03-13$星期一$小雨$9$6$11$7$99$北风$4级$2017-03-13 08:35:05$53$32$优$
void SysDialog::updateSYS(void)
{
	int pm=0;
	char buf[350];
    int hour_timer;
    QString value;

#ifdef ARM
    //pm2.5 update
	bzero(buf,350);
	if(read(fd_pm25,buf,350)>0){	
		pm = 0;
		pm = da_pro(buf);
		if(pm==-1) 
            info = "Err";
		else
			info = QString::number(pm);
	}

    get_dht_data();

    value  ="温度 " + QString::number(temp-3) + "  湿度 " + QString::number(humi) +  QString("  PM2.5  ") + info;
    showToday->setInsideVal(value);


    aqiArr[3] = QString::number(pm);//pm2.5 local

#endif

     showAqi->updateVal(aqiArr);


    //time update
    QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
    if(flag_time==1){
        sysTime->setText(time.toString("hh:mm"));
        flag_time=0;
    }else{
        sysTime->setText(time.toString("hh mm"));
        flag_time=1;
    }


    QString ctimer = time.toString("hh:mm:ss");
    //showToday->setInsideVal(ctimer);

    net_timer++;
    //运行python文件读取云端数据
    hour_timer = 60 * 60 * hourNum;

    if(hour_timer<=3600)
        hour_timer = 3600;
    if(ctimer=="00:1:30" || net_timer == hour_timer)
    {        //execute python
        net_timer = 0;
        QString program = "/usr/bin/python";
        QStringList arguments;
        arguments << "/home/pi/temp_p2_7.py" ;
        myProcess->start(program, arguments);
    }

    temp_timer++;
    //更新显示的数据
    if(temp_timer>=300 || sysSet->getFlagVal()==1){
        temp_timer = 0;
        sysSet->setFlagVal(0);
        this->get_day_value();
        showToday->updateVal(dayArr);

        this->get_week_value();
        for(int i=0;i<MAX_DAY;i++){
            showWeek[i]->updateVal(weekArr[i]);
        }

        aqiArr[0] = dayArr[13];//pm2.5
        aqiArr[1] = dayArr[12];//pm10
        aqiArr[2] = dayArr[15];//aqi
        aqiArr[4] = dayArr[0];
    }
}



int SysDialog::get_week_value(void)
{
    FILE *fp;
    char read_buf[LEN];
    char buf[LEN];
    char *p,*temp;
    int i=0,len=0,daily=0,item=0;

    bzero(read_buf,LEN);

    fp = fopen(WEEK_FILE,"r");
    if(NULL == fp){
	printf("open week_file err...\n");
	return -1;
	}

    len = fread(read_buf,1,1024,fp);
//    len= strlen(read_buf);
    printf("%s\n,len=%d\n",read_buf,len);

    p=read_buf;
    bzero(buf,LEN);
    temp = buf;

    for(i=0;i<len;i++){
        if(p[i] != '$'){
            *temp = p[i];
            temp++;
        }else{
            *temp=0;
            temp=buf;
            weekArr[daily][item] = QString(buf);
            if(++item > 7){
                item = 0;
                if(++daily > 5)
                    break;
            }
        }
    }
    fclose(fp);
    return 0;
}



int SysDialog::get_day_value(void)
{
    FILE *fp;
    char read_buf[LEN];
    char buf[LEN];
    char key_buf[32];
    char* p,*temp;
    int i=0,j=0,len=0,key_ok=0,index=0;

    bzero(read_buf,LEN);

    fp = fopen(DAY_FILE,"r");
    if(NULL == fp) return -1;

    fread(read_buf,1,1024,fp);

    printf("%s\n",read_buf);

    p=read_buf;

    bzero(buf,LEN);
    len= strlen(read_buf);
    printf("len=%d\n",len);

    temp=buf;

    for(i;i<len;i++){
        if(p[i] != '$'){
            *temp = p[i];
            temp++;
        }else{
            *temp=0;
            temp=buf;
            dayArr[index]= QString(buf);
            if(++index > 15)
                index = 0;
        }
    }
    fclose(fp);
    return 0;
}

void SysDialog::setHour(int hour)
{
    hourNum = hour;
}
